package com.m3958.firstgwt.server.servlet;

import java.io.IOException;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import redis.clients.jedis.Jedis;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Singleton;
import com.m3958.firstgwt.server.constants.PeriodContants;
import com.m3958.firstgwt.server.dao.LinkDao;
import com.m3958.firstgwt.server.dao.SectionDao;
import com.m3958.firstgwt.server.model.Link;
import com.m3958.firstgwt.server.model.Section;
import com.m3958.firstgwt.server.model.WebSite;
import com.m3958.firstgwt.server.service.AppUtilService;
import com.m3958.firstgwt.server.service.JedisPoolService;
import com.m3958.firstgwt.server.service.ReqParaService;
import com.m3958.firstgwt.shared.type.SmartConstants;

@Singleton
public class SiteJsonpServlet extends HttpServlet{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	@Inject
	private Injector injector;
	
	@Inject
	private AppUtilService autils;
	
//	if(fn.startsWith("hostname=") || fn.startsWith("remoteip=")){
	private Pattern hostipPattern = Pattern.compile("(.*)(&.*)(&.*)");
	
	@Inject
	private JedisPoolService jedis;
	
	@Inject
	protected com.google.inject.Provider<EntityManager> emp;
	
	/*
	 * 这个servlet返回的肯定是http方式的html
	 * 
	 */
	
	@Override
	public void doGet(HttpServletRequest req, HttpServletResponse res)
			throws ServletException, IOException {
		ReqParaService reqps = injector.getInstance(ReqParaService.class);
		int siteId = reqps.getIdValue("siteId");
		String callback = reqps.getStringValue("callback", "");
		if(siteId == SmartConstants.NONE_EXIST_MODEL_ID){
			autils.writeHtmlResponse(res, "siteId parameter required!");
			return;
		}
		if(callback.isEmpty()){
			autils.writeHtmlResponse(res, "callback parameter required!");
			return;
		}
		WebSite ws = emp.get().find(WebSite.class, siteId);
		if(ws == null){
			autils.writeHtmlResponse(res, "website doesn't exist!");
			return;
		}
		
		String qs = null;
		if(req.getParameter("remoteip") != null && !req.getParameter("remoteip").isEmpty()){
			Matcher m = hostipPattern.matcher(req.getQueryString());
			if(m.matches()){
				qs = m.group(1);//redis key
			}
		}
		
		String ss = null;
		Jedis jd = jedis.getInstance();
		if(qs != null){
			try {
				ss = jd.get("site:" + siteId + qs);
			} catch (Exception e) {
			}
		}
		
		if(ss == null){
			JSONObject siteJo = ws.toJson();
			siteJo.element("sections", getSectionJsonArray(siteId));
			siteJo.element("links", getLinkJsonArray(siteId));
			
			siteJo.element("sectionList", getSectionList(siteId));
			siteJo.element("linkList", getLinkList(siteId));
			ss = siteJo.toString();
			if(jd != null){
				jd.set("site:"  + siteId + qs, ss);
				jd.expire("site:"  + siteId + qs, PeriodContants.DAY_IN_SECONDS);
			}
		}
		autils.writeJsonpResponse(res, ss, callback);
	}
	
	private JSONArray getSectionList(int siteId) {
		Query q = emp.get().createNamedQuery(Section.NamedQueries.GET_ALL_SECTIONS);
		q.setParameter("siteId", siteId);
		List<Section> sections = q.getResultList();
		JSONArray sectionJsonAry = new JSONArray();
		for(Section section : sections){
			sectionJsonAry.add(section.toJson());
		}
		return sectionJsonAry;
	}
	
	private JSONArray getLinkList(int siteId) {
		Query q = emp.get().createNamedQuery(Link.NamedQueries.GET_ALL_LINKS);
		q.setParameter("siteId", siteId);
		List<Link> links = q.getResultList();
		JSONArray linkJsonAry = new JSONArray();
		for(Link link : links){
			linkJsonAry.add(link.toJson());
		}
		return linkJsonAry;
	}

	private JSONArray getSectionJsonArray(int siteId) {
		SectionDao sdao = injector.getInstance(SectionDao.class);
		List<Section> sections = sdao.getTopSections(siteId);
		JSONArray sectionJsonAry = new JSONArray();
		for(Section section : sections){
			sectionJsonAry.add(section.toJson("vvv"));
		}
		return sectionJsonAry;
	}
	
	private JSONArray getLinkJsonArray(int siteId) {
		LinkDao ldao = injector.getInstance(LinkDao.class);
		List<Link> links = ldao.getTopLinks(siteId);
		JSONArray linkJsonAry = new JSONArray();
		for(Link link : links){
			linkJsonAry.add(link.toJson("vvv"));
		}
		return linkJsonAry;
	}
}
